import { useCallback, Fragment, ReactElement, useMemo, useRef, MouseEvent } from 'react';
import { Empty, SwipeAction, Dialog, Button, Toast } from 'antd-mobile';
import { useFieldSchema } from '@formily/react';
import { SwipeActionRef } from 'antd-mobile/es/components/swipe-action';
import type { IEformDataGrid } from './schema';
import { hasAuth } from '@inbiz/basic/AuthForm';
import { inbiz } from '@inbiz/render';
import { TextWidget, getMessage } from '@inbiz/react';
import { useInbizRouter } from '@inbiz/hooks';
import {multilingualFormat} from '@inbiz/utils'
type IDataItem = {
  options?: any;
  history?: ReturnType<typeof useInbizRouter>;
  pagePath?: string;
  data: object;
  modelKey?: string;
  inbiz?: inbiz;
  columns: (Omit<
    IEformDataGrid['config']['base']['config']['showField']['showFields'][number],
    'IsMany' | 'ModelKey'
  > & { IsMany?: boolean })[];
  showDetail?: boolean;
  isCard?: boolean;
  isSwipeAction?: boolean;
  onClick?: (data: IDataItem['data']) => void;
  updateList?: any;
  showRow?: number;
  events?: any;
  emit?: any;
  radiusStyle?: string;
  auth?: any;
  modelname: string;
};
export type IswipeActionRef = {
  current: {
    close: () => void;
    show: (side?: 'left' | 'right') => void;
  };
};
function DataItem({
  data,
  columns,
  showDetail = true,
  isCard = true,
  onClick,
  options,
  history,
  pagePath,
  inbiz,
  modelKey,
  isSwipeAction,
  updateList,
  showRow,
  events,
  emit,
  radiusStyle,
  auth,
  modelname,
}: IDataItem) {
  const filedShcema = useFieldSchema()
  const tableId = filedShcema?.['x-designable-id'];
  const handleClick = useCallback(() => {
    onClick && onClick(data);
  }, [data]);
  let newColumns = columns.slice(0);
  if (showRow && newColumns.length > showRow) {
    newColumns.length = showRow;
  }
  const swipeActionRef = useRef<SwipeActionRef>(null);
  const Item = () => {
    return (
      <div
        className={`itemBox ${(isCard && 'card') || ''}`}
        style={{ borderRadius: radiusStyle, overflow: 'hidden' }}
        onClick={handleClick}
      >
        <ul>
          {newColumns.map((item) => {
            return (
              item && (
                <Fragment key={item.value}>
                  <li style={{ color: 'var(--inbiz-color-heading)' }}>
                    <TextWidget>{item.title}</TextWidget>:
                  </li>
                  <li style={{ color: 'var(--inbiz-color-text)' }}>
                    {formatValue(data[item.value], item, goChildDetail(data, item))}
                  </li>
                </Fragment>
              )
            );
          })}
        </ul>
        {showDetail && (
          <div className="detail" onClick={goMore(data)}>
            <TextWidget>Table.more</TextWidget>
          </div>
        )}
      </div>
    );
  };
  const goChildDetail = useCallback(
    (data, clomun) => (e: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>) => {
      e.stopPropagation();
      //@ts-ignore
      history.push({
        pathname: pagePath + '/childDetails',
        //@ts-ignore
        query: { id: data.id ?? data.ID ?? data.Id, field: clomun.field },
      });
    },
    [],
  );
  const goMore = useCallback(
    (data) => (e: any) => {
      if (inbiz?.browser.designer) return;
      e.stopPropagation();
      // emit?.('onClick', 'view');
      //@ts-ignore
      history.push({
        pathname: pagePath + `/${tableId}/eformtabledetails`,
        //@ts-ignore
        query: { id: data.id ?? data.ID ?? data.Id },
      });
    },
    [],
  );

  const handleSwipeAction = useCallback(async (action) => {
    let pageRout;
    (options || []).forEach((item: any) => {
      if (item.actionType == action.key) {
        pageRout = item.page?.split(',')[0];
      }
    });
    let id = action.item.id;
    const operation = options?.find((item: any) => item.actionType === action.key)!;
    if (events) {
      emit?.('onClick', action.key, operation, action.item);
      const result = await events.current.onBeforeOperationAsync?.(operation, action.item);
      if (result === false) {
        swipeActionRef.current?.close();
        return;
      }
    }
    if (action.key == 'del') {
      Dialog.confirm({
        content: getMessage('Table.tips.confirmDeletion'),
        confirmText: <TextWidget>Table.sure</TextWidget>,
        cancelText: <TextWidget>Table.cancel</TextWidget>,
        onConfirm: async () => {
          swipeActionRef.current?.close();
          const resData = await inbiz?.submit({
            modleName: modelname,
            data: [{ id, _opt: 'del' }],
            noRelation: true,
          });
          if (!resData) return;
          emit?.('ondelete', data);
          updateList!(`eformtable${action.key}`, undefined, id);
        },
      });
    } else {
      swipeActionRef.current?.close();
      emit?.(
        'onread',
        options!.filter((item: any) => {
          return item.actionType == action.key;
        })[0],
        data,
      );
      const urlData = events?.current.onOpenChildUrl?.(operation, action.data);
      // emit?.('onOpen');
      //@ts-ignore
      if (pageRout) {
        setTimeout(() => {
          history.push({
            pathname: pagePath + `/${tableId}/eformtabledetails/` + `eformtable${action.key}`,
            //@ts-ignore
            query: {
              id,
              pageRout: pageRout,
              ...urlData,
            },
          });
        }, 0)
      } else {
        Toast.show({
          content: getMessage('Table.tips.pleaseBindThePage'),
        });
      }
    }
  }, []);
  const rightActions = useMemo(() => {
    if (!isCard) return;
    return (options || [])
      .filter((item: any) => {
        if (item.actionType == 'view' || item.actionType == 'del') {
          const authFlag = hasAuth(
            {
              table: [{ ...item, operationType: item?.actionType == 'view' ? 'select' : 'delete' }],
              auth: auth,
            },
            item?.actionType == 'view' ? 'select' : 'delete',
            inbiz?.auth,
          ).auth;
          if (authFlag) return item;
        }
      })
      .map((item: any) => {
        return {
          key: item.actionType,
          text: getMessage(item.actionName),
          item: data,
          color: item.actionType === 'del' ? 'danger' : 'primary',
        };
      });
  }, [auth]);
  return (
    <SwipeAction
      rightActions={isSwipeAction && !inbiz.browser.designer ? rightActions : []}
      onAction={handleSwipeAction}
      ref={swipeActionRef}
      closeOnAction={false}
      style={{ borderRadius: radiusStyle, '--radiusStyle': radiusStyle }}
    >
      <Item />
    </SwipeAction>
  );
}

const formatValue = (
  value: string | number | boolean | { label: string; Data?: { [key: string]: unknown }[] },
  column: IDataItem['columns'][number],
  onClick: (event: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>) => void,
): string | ReactElement => {
  if (!value && value !== 0) {
    return '--';
  } else {
    if (column.IsMany) {
      const { showType, pageBtnText, separatorText, fieldList } = column.relation || {
        showType: '1',
        pageBtnText: getMessage('Table.detail'),
        separatorText: ',',
        fieldList: [],
      };
      if (showType === '1') {
        return (
          <Button color="primary" fill="none" className="goChildDetail" onClick={onClick}>
            {pageBtnText}
          </Button>
        );
      } else {
        return (
          (value as Extract<typeof value, object>)?.Data?.map(
            (item) => item[fieldList[0].field],
          ).join(separatorText) || ''
        );
      }
    } else {
      if (typeof value === 'object') {
        if (Array.isArray(value)) {
          return JSON.stringify(value);
        } else {
          return value.label !== undefined ? value.label : JSON.stringify(value);
        }
      } else {
        return multilingualFormat(value.toString());
      }
    }
  }
};

export default DataItem;
export type { IDataItem };
